package leetcode; /**
 * description:
 * author:zt
 * date:2021-07-28
 */

/**
 * 给定正整数n，找到若干个完全平方数（比如1, 4, 9, 16, ...）使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
 *
 * 给你一个整数 n ，返回和为 n 的完全平方数的 最少数量 。
 *
 * 完全平方数 是一个整数，其值等于另一个整数的平方；换句话说，其值等于一个整数自乘的积。例如，1、4、9 和 16 都是完全平方数，而 3 和 11 不是。
 */
public class leetcode279 {
    public int numSquares(int n) {
        //dp数组保存的是组成每一个数字需要的最少完全平方数量
        int[] dp = new int[n+1];
        //dp[0]=0 表示 每一个完全平方数 dp[i] = dp[0]+1 = 1即它自身
        for (int i = 1; i <= n; i++) {
            dp[i] = i;
            //则在遍历过程中，若遇到j*j<当前数的情况，则表示j*j是组成i的一个完全平方数
            //那么只需统计 组成i-j*j这个数的最少完全平方数量 这样的子问题
            //例如 数字13
            //dp数组每一位如下 dp[]={0,1,2,3,1,2,3,4,2,1,2,3,3,2}
            for (int j = 1; j*j<=i ;j ++){
                dp[i] = Math.min(dp[i],dp[i-j*j]+1);
            }
        }
        return dp[n];
    }
}

